namespace YXShop.ExcelLite
{
    using System;
    using System.Collections;

    public sealed class CellStyle
    {
        private CellStyleData element;
        internal CellStyleData.Properties UseFlags;

        public CellStyle()
        {
            this.UseFlags = CellStyleData.Properties.None;
            this.element = new CellStyleData(null, false);
        }

        internal CellStyle(CellStyleCachedCollection styleCollection)
        {
            this.UseFlags = CellStyleData.Properties.None;
            this.element = (CellStyleData) styleCollection.DefaultElement;
        }

        internal CellStyle(CellStyle style, WeakHashtable parentCollection)
        {
            this.UseFlags = CellStyleData.Properties.None;
            this.element = style.element;
            if (!(this.element.IsInCache && (this.element.ParentCollection == parentCollection)))
            {
                this.CloneElement(parentCollection);
                this.AddToQueue();
            }
            this.UseFlags = style.UseFlags;
        }

        private void AddToQueue()
        {
            WeakHashtable parentCollection = this.element.ParentCollection;
            Queue addQueue = parentCollection.AddQueue;
            if (addQueue.Count >= parentCollection.AddQueueSize)
            {
                ((CellStyle) addQueue.Dequeue()).Consolidate();
            }
            addQueue.Enqueue(this);
        }

        internal void BeforeChange()
        {
            if (this.element.IsInCache)
            {
                this.CloneElement(this.element.ParentCollection);
                this.AddToQueue();
            }
        }

        private void CloneElement(WeakHashtable parentCollection)
        {
            this.element = (CellStyleData) this.element.Clone(parentCollection);
        }

        internal void Consolidate()
        {
            this.element = (CellStyleData) this.element.FindExistingOrAddToCache();
        }

        internal void CopyIfNotUsed(CellStyle lowerPriority)
        {
            CellStyleData element = this.element;
            CellStyleData data2 = lowerPriority.element;
            if ((this.UseFlags & CellStyleData.Properties.HorizontalAlignment) == CellStyleData.Properties.None)
            {
                element.HorizontalAlignment = data2.HorizontalAlignment;
            }
            if ((this.UseFlags & CellStyleData.Properties.VerticalAlignment) == CellStyleData.Properties.None)
            {
                element.VerticalAlignment = data2.VerticalAlignment;
            }
            if ((this.UseFlags & CellStyleData.Properties.PatternStyle) == CellStyleData.Properties.None)
            {
                element.PatternStyle = data2.PatternStyle;
            }
            if ((this.UseFlags & CellStyleData.Properties.PatternBackgroundColor) == CellStyleData.Properties.None)
            {
                element.PatternBackgroundColor = data2.PatternBackgroundColor;
            }
            if ((this.UseFlags & CellStyleData.Properties.PatternForegroundColor) == CellStyleData.Properties.None)
            {
                element.PatternForegroundColor = data2.PatternForegroundColor;
            }
            if ((this.UseFlags & CellStyleData.Properties.Indent) == CellStyleData.Properties.None)
            {
                element.Indent = data2.Indent;
            }
            if ((this.UseFlags & CellStyleData.Properties.Rotation) == CellStyleData.Properties.None)
            {
                element.Rotation = data2.Rotation;
            }
            if ((this.UseFlags & CellStyleData.Properties.Locked) == CellStyleData.Properties.None)
            {
                element.Locked = data2.Locked;
            }
            if ((this.UseFlags & CellStyleData.Properties.FormulaHidden) == CellStyleData.Properties.None)
            {
                element.FormulaHidden = data2.FormulaHidden;
            }
            if ((this.UseFlags & CellStyleData.Properties.WrapText) == CellStyleData.Properties.None)
            {
                element.WrapText = data2.WrapText;
            }
            if ((this.UseFlags & CellStyleData.Properties.ShrinkToFit) == CellStyleData.Properties.None)
            {
                element.ShrinkToFit = data2.ShrinkToFit;
            }
            if ((this.UseFlags & CellStyleData.Properties.NumberFormat) == CellStyleData.Properties.None)
            {
                element.NumberFormat = data2.NumberFormat;
            }
            if ((this.UseFlags & CellStyleData.Properties.FontName) == CellStyleData.Properties.None)
            {
                element.FontData.Name = data2.FontData.Name;
            }
            if ((this.UseFlags & CellStyleData.Properties.FontColor) == CellStyleData.Properties.None)
            {
                element.FontData.Color = data2.FontData.Color;
            }
            if ((this.UseFlags & CellStyleData.Properties.FontWeight) == CellStyleData.Properties.None)
            {
                element.FontData.Weight = data2.FontData.Weight;
            }
            if ((this.UseFlags & CellStyleData.Properties.FontSize) == CellStyleData.Properties.None)
            {
                element.FontData.Size = data2.FontData.Size;
            }
            if ((this.UseFlags & CellStyleData.Properties.FontItalic) == CellStyleData.Properties.None)
            {
                element.FontData.Italic = data2.FontData.Italic;
            }
            if ((this.UseFlags & CellStyleData.Properties.FontStrikeout) == CellStyleData.Properties.None)
            {
                element.FontData.Strikeout = data2.FontData.Strikeout;
            }
            if ((this.UseFlags & CellStyleData.Properties.FontScriptPosition) == CellStyleData.Properties.None)
            {
                element.FontData.ScriptPosition = data2.FontData.ScriptPosition;
            }
            if ((this.UseFlags & CellStyleData.Properties.FontUnderlineStyle) == CellStyleData.Properties.None)
            {
                element.FontData.UnderlineStyle = data2.FontData.UnderlineStyle;
            }
            for (int i = 0; i < 4; i++)
            {
                if ((element.BordersUsed & CellBorder.MultipleFromIndividualBorder((IndividualBorder) i)) == MultipleBorders.None)
                {
                    element.BorderColor[i] = data2.BorderColor[i];
                    element.BorderStyle[i] = data2.BorderStyle[i];
                }
            }
            if ((element.BordersUsed & MultipleBorders.Diagonal) == MultipleBorders.None)
            {
                element.BorderColor[4] = data2.BorderColor[4];
                element.BorderStyle[4] = data2.BorderStyle[4];
            }
            element.BordersUsed |= data2.BordersUsed;
            this.UseFlags |= lowerPriority.UseFlags;
        }

        public CellBorders Borders
        {
            get
            {
                return new CellBorders(this);
            }
            set
            {
                this.BeforeChange();
                value.CopyTo(this);
            }
        }

        internal CellStyleData Element
        {
            get
            {
                return this.element;
            }
        }

        public ExcelFillPattern FillPattern
        {
            get
            {
                return new ExcelFillPattern(this);
            }
            set
            {
                this.BeforeChange();
                value.CopyTo(this);
            }
        }

        public ExcelFont Font
        {
            get
            {
                return new ExcelFont(this);
            }
            set
            {
                this.BeforeChange();
                value.CopyTo(this);
            }
        }

        public bool FormulaHidden
        {
            get
            {
                return this.element.FormulaHidden;
            }
            set
            {
                this.BeforeChange();
                this.element.FormulaHidden = value;
                this.UseFlags |= CellStyleData.Properties.FormulaHidden;
            }
        }

        public HorizontalAlignmentStyle HorizontalAlignment
        {
            get
            {
                return this.element.HorizontalAlignment;
            }
            set
            {
                this.BeforeChange();
                this.element.HorizontalAlignment = value;
                this.UseFlags |= CellStyleData.Properties.HorizontalAlignment;
            }
        }

        public int Indent
        {
            get
            {
                return this.element.Indent;
            }
            set
            {
                if ((value < 0) || (value > 15))
                {
                    throw new ArgumentOutOfRangeException("value", value, "Indent must be between 0 and 15.");
                }
                this.BeforeChange();
                this.element.Indent = value;
                this.UseFlags |= CellStyleData.Properties.Indent;
            }
        }

        public bool IsDefault
        {
            get
            {
                return object.ReferenceEquals(this.element, this.element.ParentCollection.DefaultElement);
            }
        }

        public bool IsTextVertical
        {
            get
            {
                return (this.element.Rotation == 0xff);
            }
            set
            {
                if (this.IsTextVertical)
                {
                    if (!value)
                    {
                        this.Rotation = 0;
                    }
                }
                else if (value)
                {
                    this.BeforeChange();
                    this.element.Rotation = 0xff;
                    this.UseFlags |= CellStyleData.Properties.Rotation;
                }
            }
        }

        public bool Locked
        {
            get
            {
                return this.element.Locked;
            }
            set
            {
                this.BeforeChange();
                this.element.Locked = value;
                this.UseFlags |= CellStyleData.Properties.Locked;
            }
        }

        public string NumberFormat
        {
            get
            {
                return this.element.NumberFormat;
            }
            set
            {
                this.BeforeChange();
                this.element.NumberFormat = value;
                this.UseFlags |= CellStyleData.Properties.NumberFormat;
            }
        }

        public int Rotation
        {
            get
            {
                if (this.IsTextVertical)
                {
                    return 0;
                }
                return this.element.Rotation;
            }
            set
            {
                if (value != this.Rotation)
                {
                    if ((value < -90) || (value > 90))
                    {
                        throw new ArgumentOutOfRangeException("value", value, "Rotation must be between -90 and 90.");
                    }
                    this.BeforeChange();
                    if (value >= 0)
                    {
                        this.element.Rotation = value;
                    }
                    else
                    {
                        this.element.Rotation = 90 - value;
                    }
                    this.UseFlags |= CellStyleData.Properties.Rotation;
                }
            }
        }

        public bool ShrinkToFit
        {
            get
            {
                return this.element.ShrinkToFit;
            }
            set
            {
                this.BeforeChange();
                this.element.ShrinkToFit = value;
                this.UseFlags |= CellStyleData.Properties.ShrinkToFit;
            }
        }

        public VerticalAlignmentStyle VerticalAlignment
        {
            get
            {
                return this.element.VerticalAlignment;
            }
            set
            {
                this.BeforeChange();
                this.element.VerticalAlignment = value;
                this.UseFlags |= CellStyleData.Properties.VerticalAlignment;
            }
        }

        public bool WrapText
        {
            get
            {
                return this.element.WrapText;
            }
            set
            {
                this.BeforeChange();
                this.element.WrapText = value;
                this.UseFlags |= CellStyleData.Properties.WrapText;
            }
        }
    }
}

